﻿// owner 蒋家伟

#pragma once

#include <type_traits>

namespace jsdk
{
    // 当前文档中的方法均支持编译期计算

    // 类型描述 : 传入指数index 求 2的幂计算
    template<int index>
    struct Power_Two
    {
        static_assert(index < 64 && index >= 0, "index range in [1,64]");
        static constexpr uint64_t value = static_cast<uint64_t>(1) << index;
    };

    template<uint64_t ivalue>
    struct Is_Power_Two
    {
        static_assert(ivalue > 0, "value need greater 0");
        static constexpr bool value = ((ivalue & (ivalue - 1)) == 0);
    };

    // 类型描述 : 传入指数index ,从0到index位 全部置1
    // 举例 : Complete_One<5>::value = 0b111111, Complete_One<4>::value = 0b11111, Complete_One<0>::value = 0b1
    template<int index>
    struct Complete_One
    {
        static_assert(index < 63 && index >= 0, "index range in [1,64]");
        static constexpr uint64_t value = Power_Two<index + 1>::value - 1;
    };

    template<>
    struct Complete_One<63>
    {
        static constexpr uint64_t value = 0xFF'FF'FF'FF'FF'FF'FF'FF;
    };

    // 类型描述 : 判断传入的数字的对应的index位是否为1
    // note : 只支持整数类型
    // 举例 : index_Bit_is_One<5>(32) = true, index_Bit_is_One<0>(32) = false,  index_Bit_is_One<1>(32) = false, ....
    template<int index, typename T, typename = std::enable_if_t<std::is_integral<T>::value, void>>
    constexpr bool index_Bit_is_One(const T& tvalue)
    {
        static_assert(sizeof(T) > 0 && sizeof(T) <= sizeof(uint64_t), "T size need lesser sizeof(uint64_t)");
        return (tvalue & Power_Two<index>::value) != 0;
    };

    // 类型描述 : 获取起始下标到结束下标 位的值
    // note : 支持无符号整形
    // 举例 : getIndexSectionValue<0, 5>(32) = 32 , getIndexSectionValue<1, 5>(32) = 16, getIndexSectionValue<2, 5>(32) = 8
    template<int sIndex, int eIndex, typename T>
    constexpr T getIndexSectionValue(const T& tvalue, IS_CLASS_TYPE(std::is_integral<T>::value && std::is_unsigned<T>::value) )
    {
        static_assert(sizeof(T) > 0 && sizeof(T) <= sizeof(uint64_t), "T size need lesser sizeof(uint64_t)");
        return static_cast<T>((tvalue & Complete_One<eIndex>::value) >> sIndex);
    };

    // 类型描述 : 获取起始下标到结束下标 位的值
    // note : 支持有符号整形
    // 举例 : 同无符号
    template<int sIndex, int eIndex, typename T>
    constexpr T getIndexSectionValue(const T& tvalue, IS_CLASS_TYPE(std::is_integral<T>::value && std::is_signed<T>::value) )
    {
        static_assert(sizeof(T) > 0 && sizeof(T) <= sizeof(uint64_t), "T size need lesser sizeof(uint64_t)");
        return static_cast<T>((tvalue & Complete_One<eIndex>::value) >> sIndex);
    };
}
